﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using PharmClientService.ServParsSite;
using System.Configuration;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading;
using System.Timers;
using System.Configuration.Install;
using System.Reflection;

namespace PharmClientService
{
    public partial class PharmClientService : ServiceBase
    {
        private int trynumber = 1;
        private int check_instal = 1;
        private ServParsSiteClient client = new ServParsSiteClient();
        private int clientid = 0;
        private System.Timers.Timer aTimer;
        private string curdir = "";

        public PharmClientService()
        {
            InitializeComponent();
            if (!System.Diagnostics.EventLog.SourceExists("PharmClientServiceSource"))
            {
                System.Diagnostics.EventLog.CreateEventSource("PharmClientServiceSource", "PharmClientServiceLog");
            }
            eventLog1.Source = "PharmClientServiceSource";
            eventLog1.Log = "PharmClientServiceLog";
        }

        protected override void OnStart(string[] args)
        {
            string log = "Запуск службы!";
            try
            {
                Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                clientid = Convert.ToInt32(config.AppSettings.Settings["clientid"].Value);
                log += "\nTекущее значение clientid = " + clientid;
                curdir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                string ip = GetIP();
                if (clientid == 0)
                {
                    string comment = Environment.MachineName;                
                    log += "\n Получение списка и версий exe-файлов";                  
                    string[] filelist = Directory.GetFiles(curdir, "*.exe");

                    DataTable files = new DataTable("files");
                    files.Columns.Add("fileid");
                    files.Columns.Add("filename");
                    files.Columns.Add("fileversion");
                    foreach (string s in filelist)
                    {
                        object[] row = new object[3] { null, Path.GetFileName(s), FileVersionInfo.GetVersionInfo(s).FileVersion };
                        files.Rows.Add(row);
                    }

                    clientid = client.NewClient(ip, comment, files);
                    log += "\n\nЗапись в config значений:\nclientid = " + clientid + "\nip = " + ip + "\ncomment = " + comment;
                    config.AppSettings.Settings["clientid"].Value = clientid.ToString();
                    config.AppSettings.Settings["ip"].Value = ip;
                    config.AppSettings.Settings["comment"].Value = comment;
                    config.Save(ConfigurationSaveMode.Modified);
                    ConfigurationManager.RefreshSection("appSettings");
                    log += "\nЗначения сохранены";
                }
                else
                {
                    if (config.AppSettings.Settings["ip"].Value != ip)
                    {
                        log += "\n\nИзменение старого IP:\nстарый IP = " + config.AppSettings.Settings["ip"].Value + "\nновый IP = " + ip;
                        client.ClientIPUpd(clientid, ip);
                        config.AppSettings.Settings["ip"].Value = ip;
                        config.Save(ConfigurationSaveMode.Modified);
                        ConfigurationManager.RefreshSection("appSettings");
                        log += "\nIP изменен";
                    }
                }
                log += "\n\nЗапуск таймера";
                aTimer = new System.Timers.Timer(60000);
                aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
                aTimer.Enabled = true;
                if (aTimer.Enabled) log += "\nТаймер активен";
                else log += "\nТаймер не активен";

                
            }
            catch (Exception ex)
            {
                eventLog1.WriteEntry(ex.Message);
            }

            eventLog1.WriteEntry(log);
        }

        protected override void OnStop()
        {
            eventLog1.WriteEntry("Остановка службы");
        }

        private void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            string log = "Попытка № " + trynumber;
            bool fl_b = false;
            try
            {
                WorkPlanStr wps = (WorkPlanStr)client.IAmFree(clientid);
                log += "\nDrug = " + wps.Drug + "; UrlPath = " + wps.UrlPath + "; UrlParam = " + wps.UrlParam + "; WorkPlanStrID = " + wps.WorkPlanStrID + "; WebSiteID = " + wps.WebSiteID;

                if (wps.WebSiteID != 0)
                {
                    ParsingSites ps = new ParsingSites();
                    DataTable CompPrice = ps.SitePars(wps.UrlPath, wps.UrlParam.Replace("***", System.Uri.EscapeDataString(wps.Drug)), wps.WebSiteID, wps.Drug, "");
                    CompPrice.TableName = "CompPrice";
                    CompPrice.Columns.Add("parentid");
                    client.CompPriceIns(CompPrice, wps.WorkPlanStrID, clientid);
                    fl_b = true;
                }
            }
            catch (Exception ex)
            {
                eventLog1.WriteEntry(ex.Message);
            }
            if (fl_b) log += "\nУСПЕХ";
            else log += "\nОШИБКА";

            try
            {
                if (check_instal == 5)
                {
                    FileNameVersion fnv = (FileNameVersion)client.GetInstallerInfo();
                    if (fnv.FileName != "")
                    {
                        log += "\n\nПроверка обновлений";
                        string currfile = curdir + @"\" + fnv.FileName;
                        string currvers = FileVersionInfo.GetVersionInfo(currfile).FileVersion;
                        if (currvers != fnv.FileVersion)
                        {
                            log += "\nЗагрузка обновлений";
                            var chukscount = client.GetFileChunksCount(fnv.FileName);
                            var stream = File.Create(currfile);
                            for (var i = 0; i < chukscount; i++)
                            {
                                var chunk = client.GetFileChunk(fnv.FileName, i);
                                var chunkBytes = Convert.FromBase64String(chunk);
                                stream.Write(chunkBytes, 0, chunkBytes.Length);
                            }
                            stream.Close();
                            log += "\nОбновления загружены";
                            client.ClientFileVersionUpd(clientid, fnv.FileName, FileVersionInfo.GetVersionInfo(currfile).FileVersion);
                            //log += "\nclient.ClientFileVersionUpd(" + clientid.ToString() + "," + fnv.FileName + "," + FileVersionInfo.GetVersionInfo(currfile).FileVersion;
                            log += "\nОстановка таймера";
                            aTimer.Stop();
                            log += "\nЗапуск инсталятора";
                            Process.Start(currfile, "-upd -" + clientid.ToString());
                        }
                    }
                    check_instal = 0;
                }
            }
            catch (Exception ex)
            {
                eventLog1.WriteEntry(ex.Message);
            }

            check_instal++;  
            trynumber++;
            eventLog1.WriteEntry(log);
        }

        string GetIP()
        {
            string ip = "";
            WebClient client = new WebClient();
            Stream stream = client.OpenRead("http://www.ip-ping.ru/");
            StreamReader sr = new StreamReader(stream);
            string newLine;
            Regex regex = new Regex("<div class=\"hc2\">(.*)</div>");
            while ((newLine = sr.ReadLine()) != null)
            {
                Match match = regex.Match(newLine);
                string str = match.Groups[1].ToString();
                if (str != "") ip = str;
            }
            stream.Close();

            return ip;
        }

    }
}
